/*
 * Copyright (c) 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.api.client.generator.discovery.model;

import com.google.api.client.generator.common.java.JavaUtil;
import com.google.api.client.generator.linewrap.StringUtils;
import com.google.api.services.discovery.model.Jsonschema;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;

/**
 * @author Yaniv Inbar
 */
public final class PropertyModel extends SchemaBasedModel {
  private final ClassModel parent;
  private final ClassModel object;
  private final ArrayItemModel arrayItem;
  private final int arrayCount;

  PropertyModel(ImmutableMap.Builder<String, ClassModel> classModelBuilder, ClassModel parent,
      String name, Jsonschema schema) {
    super(parent.getParentService(), name, schema);
    this.parent = parent;
    ClassModel objectValue = null;
    ArrayItemModel arrayItemValue = null;
    int arrayCountValue = 0;
    switch (getType()) {
      case OBJECT:
        objectValue =
            new ClassModel(classModelBuilder, getParentService(), getObjectName(), schema);
        break;
      case ARRAY:
        Jsonschema arrSchema = getSchema();
        do {
          arrayCountValue++;
          arrSchema = arrSchema.getItems();
        } while ("array".equals(arrSchema.getType()));
        if (Type.OBJECT == computeType(arrSchema)) {
          objectValue =
              new ClassModel(classModelBuilder, getParentService(), getObjectName(), arrSchema);
        } else {
          arrayItemValue = new ArrayItemModel(parent.getParentService(), arrSchema);
        }
        break;
    }
    object = objectValue;
    arrayItem = arrayItemValue;
    arrayCount = arrayCountValue;
  }

  public ClassModel getParentClassModel() {
    return parent;
  }

  public String getWireName() {
    if (JavaUtil.isReserved(getName())) {
      return getName() + "Value";
    }
    return getName();
  }

  public ClassModel getObject() {
    Preconditions.checkState(getType() == Type.OBJECT);
    return object;
  }

  public SchemaBasedModel getArray() {
    Preconditions.checkState(getType() == Type.ARRAY);
    return object != null ? object : arrayItem;
  }

  public int getArrayCount() {
    return arrayCount;
  }

  public String getGetterMethodName() {
    return "get" + StringUtils.upperCaseFirstLetter(getName());
  }

  public String getSetterMethodName() {
    return "set" + StringUtils.upperCaseFirstLetter(getName());
  }

  String getObjectName() {
    return parent.getName() + StringUtils.upperCaseFirstLetter(getName());
  }
}
